/**********************************************************************
 *** *                                                            * ***
 *** *  Copyright (c) 2013 Harmonia Holdings Group LLC            * ***
 *** *                                                            * ***
 *** * Permission is hereby granted to use, modify, copy, and     * ***
 *** * distribute this software and its documentation for any     * ***
 *** * purpose only without profit, provided that the above       * ***
 *** * Copyright Notice appears in all copies and that both the   * ***
 *** * Copyright Notice and this Permission Notice appears in     * ***
 *** * every copy of supporting documentation.  No title to nor   * ***
 *** * ownership of the software is transferred hereby.  The name * ***
 *** * of Harmonia Holdings Group LLC shall not be used in        * ***
 *** * advertising or publicity related to the distribution of    * ***
 *** * the software without specific, written, prior permission.  * ***
 *** * This software is provided as-delivered without expressed   * ***
 *** * or implied warranty.  Harmonia Holdings Group LLC          * ***
 *** * makes no representation about the suitability of this      * ***
 *** * software for any purpose and accepts no responsibility for * ***
 *** * its use.                                                   * ***
 *** *                                                            * ***
 *** ************************************************************** ***
 *** *                                                            * ***
 *** * This program is free software; you can redistribute it     * ***
 *** * and/or modify it under the terms of the GNU General Public * ***
 *** * License as published by the Free Software Foundation;      * ***
 *** * either version 2 of the License, or (at your option) any   * ***
 *** * later version.                                             * ***
 *** *                                                            * ***
 *** * This program is distributed in the hope that it will be    * ***
 *** * useful, but WITHOUT ANY WARRANTY; without even the implied * ***
 *** * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR    * ***
 *** * PURPOSE.  See the GNU General Public License for more      * ***
 *** * details.                                                   * ***
 *** *                                                            * ***
 *** * You should have received a copy of the GNU General Public  * ***
 *** * License along with this program; if not, write to the Free * ***
 *** * Software Foundation, Inc., 51 Franklin Street, Fifth       * ***
 *** * Floor, Boston, MA 02110-1301, USA.                         * ***
 *** *                                                            * ***
 *** * For more information: http://www.gnu.org/licenses/gpl.html * ***
 *** *                                                            * ***
 **********************************************************************/
package org.etexascode.interrep.datamodel;
import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
 * The signal indication model.
 * @author ablatt
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class SignalIndication implements Serializable {
	/** Serial ID. */
	@XmlTransient
	private static final long serialVersionUID = 2914168026124667461L;


	/** Color enumeration. */
	@XmlType
	@XmlEnum
	public enum Color {
		GREEN, RED, YELLOW, NONE
	};

	/** Type enumeration. */
	@XmlType
	@XmlEnum
	public enum Type {
		BALL, LEFT_ARROW, RIGHT_ARROW, STRAIGHT_ARROW, UTURN_ARROW, STOP_SIGN, YIELD_SIGN, UNCONTROLLED, UNKNOWN
	};

	/** State enumeration. */
	@XmlType
	@XmlEnum
	public enum State {
		STEADY, FLASHING, SOFT
	};

	/** Signal ID. */
	@XmlElement
	private int laneId;

	/** Color Indication. */
	@XmlElement
	private Color colorIndication;

	/** Type indication. */
	@XmlElement
	private Type typeIndication;

	/** State indication. */
	@XmlElement
	private State stateIndication;

	/** Time to change. */
	@XmlElement
	private double timeToChange;


	/** String representation. */
	@Override
	public String toString() {
		StringBuilder ret = new StringBuilder();

		ret.append("laneId = ");
		ret.append(laneId);
		ret.append("\n");
		ret.append("colorIndication = ");
		String col = colorIndication == null ? "null" : colorIndication.name();
		ret.append(col);
		ret.append("\n");
		ret.append("typeIndication = ");
		String typ = typeIndication == null ? "null" : typeIndication.name();
		ret.append(typ);
		ret.append("\n");
		ret.append("stateIndication = ");
		String sta = stateIndication == null ? "null" : stateIndication.name();
		ret.append(sta);
		ret.append("\n");
		ret.append("timeTochange = ");
		ret.append(timeToChange);
		ret.append("\n");

		return ret.toString();
	}

	/** Check if two signal indications are equal. */
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof SignalIndication) {
			SignalIndication rhs = (SignalIndication) obj;
			return new EqualsBuilder().
					append(laneId, rhs.laneId).
					append(colorIndication, rhs.colorIndication).
					append(typeIndication, rhs.typeIndication).
					append(stateIndication, rhs.stateIndication).
					append(timeToChange, rhs.timeToChange).
					isEquals();
		}
		return false;
	}

	/**
	 * HashCode operation. 
	 * @return A hashcode of the data. 
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(61, 67).
				append(laneId).
				append(colorIndication).
				append(typeIndication).
				append(stateIndication).
				append(timeToChange).
				toHashCode();
	}
	
	/**
	 * Gets the lane ID.
	 * @return The lane ID.
	 */
	public int getLaneId() {
		return laneId;
	}

	/**
	 * Sets the lane ID.
	 * @param laneId The new lane ID.
	 */
	public void setLaneId(int laneId) {
		this.laneId = laneId;
	}

	/**
	 * Gets the color indication.
	 * @return The color indication.
	 */
	public Color getColorIndication() {
		return colorIndication;
	}

	/**
	 * Sets the color indication.
	 * @param colorIndication The new color indication.
	 */
	public void setColorIndication(Color colorIndication) {
		this.colorIndication = colorIndication;
	}

	/**
	 * Gets the type indication.
	 * @return The type indication.
	 */
	public Type getTypeIndication() {
		return typeIndication;
	}

	/**
	 * Sets the type indication.
	 * @param typeIndication The type indication.
	 */
	public void setTypeIndication(Type typeIndication) {
		this.typeIndication = typeIndication;
	}

	/**
	 * Gets the state indication.
	 * @return The state indication.
	 */
	public State getStateIndication() {
		return stateIndication;
	}

	/**
	 * Sets the state indication.
	 * @param stateIndication The new state indication.
	 */
	public void setStateIndication(State stateIndication) {
		this.stateIndication = stateIndication;
	}

	/**
	 * Gets the time to change.
	 * @return The time to change.
	 */
	public double getTimeToChange() {
		return timeToChange;
	}

	/**
	 * Sets the time to change.
	 * @param timeToChange The new time to change.
	 */
	public void setTimeToChange(double timeToChange) {
		this.timeToChange = timeToChange;
	}
}